/*
 *  Light.cpp
 *  GLRender
 *
 *  Created by Patrick zulian on 5/27/10.
 *  Copyright 2010 University  of Lugano. All rights reserved.
 *
 */

#include "Light.h"


static bool LIGTH_QUEUE_INITIALIZED = false;
static std::queue<GLenum> AVAILABLE_LIGHTS;

void 
Light::initLights()
{
	AVAILABLE_LIGHTS.push(GL_LIGHT0);
	AVAILABLE_LIGHTS.push(GL_LIGHT1);
	AVAILABLE_LIGHTS.push(GL_LIGHT2);
	AVAILABLE_LIGHTS.push(GL_LIGHT3);
	AVAILABLE_LIGHTS.push(GL_LIGHT4);
	AVAILABLE_LIGHTS.push(GL_LIGHT5);
	AVAILABLE_LIGHTS.push(GL_LIGHT6);
	AVAILABLE_LIGHTS.push(GL_LIGHT7);

	LIGTH_QUEUE_INITIALIZED = true;
}
Light * Light::newLight(const WMaterial &mat, const Point3d &position)
{
	if(!LIGTH_QUEUE_INITIALIZED) {
		initLights();
	}
	if (AVAILABLE_LIGHTS.empty()) {
		return NULL;
	}
	
	GLenum ln = AVAILABLE_LIGHTS.front();
	AVAILABLE_LIGHTS.pop();
	return new Light(mat, position, ln );
	
}

Light::~Light() 
{ 
	AVAILABLE_LIGHTS.push(lightNumber);
}


Light::Light(const WMaterial &mat, const Point3d &position, const int lightNumber)
: mat(mat), position(position), lightNumber(lightNumber)
{
	
}

void 
Light::setParam(GLenum key, const Point3d & value)
{
	params[key] = value;
		   
}

void 
Light::set()
{
	mat.setForLight(lightNumber);
	float light_pos[4] = { position.x(), position.y(), position.z(), 1.0 };
	
	glLightfv ( lightNumber, GL_POSITION, light_pos);
	
	
	for (std::map<GLenum, Point3d>::iterator it = params.begin(); it != params.end(); ++it) {
		const Point3d val = it->second;
		GLfloat vals[4] = { val.x(), val.y(), val.z(), 1.0 };
		glLightfv(lightNumber, it->first, vals );
	}
	glEnable( lightNumber );
}

